/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.mocker.jmock;

import picounit.ByteArrayParameterConstraints;
import picounit.DoubleParameterConstraints;
import picounit.IntegerParameterConstraints;
import picounit.LongParameterConstraints;
import picounit.ObjectParameterConstraints;
import picounit.StringParameterConstraints;
import picounit.Verify;
import picounit.features.base.ProxyFactory;
import picounit.features.parameter_constraints.JMockConstraints;
import previous.picounit.DelegateVerify;
import previous.picounit.TestCase;

public class JMockConstraintsTest extends TestCase {
	private final IntegerParameterConstraints integerParameterConstraints = injectCollaborator();
	private final LongParameterConstraints longParameterConstraints = injectCollaborator();
	private final DoubleParameterConstraints doubleParameterConstraints = injectCollaborator();
	private final StringParameterConstraints stringParameterConstraints = injectCollaborator();
	private final ObjectParameterConstraints objectParameterConstraints = injectCollaborator();
	private final ByteArrayParameterConstraints byteArrayParameterConstraints = injectCollaborator();
	
	private final Verify verify = injectCollaborator();
	private ProxyFactory proxyFactory;
	
	private final JMockConstraints	jmockConstraintFactory = new JMockConstraints(
		integerParameterConstraints, longParameterConstraints, doubleParameterConstraints, stringParameterConstraints,
		objectParameterConstraints, byteArrayParameterConstraints, proxyFactory, verify);

	public void testDelegatesToIntegerConstraints(DelegateVerify should) {
		should.delegateTo(integerParameterConstraints.anInteger())
			.whenCalling(jmockConstraintFactory.anInteger());

		should.delegateTo(integerParameterConstraints.oneOf(severalIntegers()))
			.whenCalling(jmockConstraintFactory.oneOf(severalIntegers()));

		should.delegateTo(integerParameterConstraints.neitherOf(severalIntegers()))
			.whenCalling(jmockConstraintFactory.neitherOf(severalIntegers()));
		
		should.delegateTo(integerParameterConstraints.notEqualTo(400))
			.whenCalling(jmockConstraintFactory.notEqualTo(400));

		should.delegateTo(integerParameterConstraints.lessThan(400))
			.whenCalling(jmockConstraintFactory.lessThan(400));
		
		should.delegateTo(integerParameterConstraints.lessThanOrEqualTo(400))
			.whenCalling(jmockConstraintFactory.lessThanOrEqualTo(400));

		should.delegateTo(integerParameterConstraints.greaterThan(400))
			.whenCalling(jmockConstraintFactory.greaterThan(400));

		should.delegateTo(integerParameterConstraints.greaterThanOrEqualTo(400))
			.whenCalling(jmockConstraintFactory.greaterThanOrEqualTo(400));
		
		should.delegateTo(integerParameterConstraints.between(100, 200))
			.whenCalling(jmockConstraintFactory.between(100, 200));
	
		should.delegateTo(integerParameterConstraints.notBetween(100, 200))
			.whenCalling(jmockConstraintFactory.notBetween(100, 200));
	
		should.delegateTo(integerParameterConstraints.almostEqualTo(100, 200))
			.whenCalling(jmockConstraintFactory.almostEqualTo(100, 200));
	}
	
	public void testDelegatesToLongConstraints(DelegateVerify should) {
		should.delegateTo(longParameterConstraints.aLong())
			.whenCalling(jmockConstraintFactory.aLong());

		should.delegateTo(longParameterConstraints.oneOf(severalLongs()))
			.whenCalling(jmockConstraintFactory.oneOf(severalLongs()));

		should.delegateTo(longParameterConstraints.neitherOf(severalLongs()))
			.whenCalling(jmockConstraintFactory.neitherOf(severalLongs()));

		should.delegateTo(longParameterConstraints.notEqualTo(100L))
			.whenCalling(jmockConstraintFactory.notEqualTo(100L));

		should.delegateTo(longParameterConstraints.lessThan(100L))
			.whenCalling(jmockConstraintFactory.lessThan(100L));

		should.delegateTo(longParameterConstraints.lessThanOrEqualTo(100L))
			.whenCalling(jmockConstraintFactory.lessThanOrEqualTo(100L));

		should.delegateTo(longParameterConstraints.greaterThan(100L))
			.whenCalling(jmockConstraintFactory.greaterThan(100L));

		should.delegateTo(longParameterConstraints.greaterThanOrEqualTo(100L))
			.whenCalling(jmockConstraintFactory.greaterThanOrEqualTo(100L));

		should.delegateTo(longParameterConstraints.between(100L, 200L))
			.whenCalling(jmockConstraintFactory.between(100L, 200L));

		should.delegateTo(longParameterConstraints.notBetween(100L, 200L))
			.whenCalling(jmockConstraintFactory.notBetween(100L, 200L));

		should.delegateTo(longParameterConstraints.almostEqualTo(100L, 20L))
			.whenCalling(jmockConstraintFactory.almostEqualTo(100L, 20L));
	}
	
	public void testDelegatesToDoubleConstraints(DelegateVerify should) {
		should.delegateTo(doubleParameterConstraints.aDouble())
			.whenCalling(jmockConstraintFactory.aDouble());

		should.delegateTo(doubleParameterConstraints.oneOf(severalDoubles()))
			.whenCalling(jmockConstraintFactory.oneOf(severalDoubles()));

		should.delegateTo(doubleParameterConstraints.neitherOf(severalDoubles()))
			.whenCalling(jmockConstraintFactory.neitherOf(severalDoubles()));

		should.delegateTo(doubleParameterConstraints.notEqualTo(123.456))
			.whenCalling(jmockConstraintFactory.notEqualTo(123.456));

		should.delegateTo(doubleParameterConstraints.lessThan(123.456))
			.whenCalling(jmockConstraintFactory.lessThan(123.456));

		should.delegateTo(doubleParameterConstraints.lessThanOrEqualTo(123.456))
			.whenCalling(jmockConstraintFactory.lessThanOrEqualTo(123.456));

		should.delegateTo(doubleParameterConstraints.greaterThan(123.456))
			.whenCalling(jmockConstraintFactory.greaterThan(123.456));

		should.delegateTo(doubleParameterConstraints.greaterThanOrEqualTo(123.456))
			.whenCalling(jmockConstraintFactory.greaterThanOrEqualTo(123.456));

		should.delegateTo(doubleParameterConstraints.between(123.456, 654.321))
			.whenCalling(jmockConstraintFactory.between(123.456, 654.321));

		should.delegateTo(doubleParameterConstraints.notBetween(123.456, 654.321))
			.whenCalling(jmockConstraintFactory.notBetween(123.456, 654.321));

		should.delegateTo(doubleParameterConstraints.almostEqualTo(123.456, 654.321))
			.whenCalling(jmockConstraintFactory.almostEqualTo(123.456, 654.321));
	}

	public void testDelegatesToStringConstraints(DelegateVerify should) {
		should.delegateTo(stringParameterConstraints.aString())
			.whenCalling(jmockConstraintFactory.aString());

		should.delegateTo(stringParameterConstraints.aNullString())
			.whenCalling(jmockConstraintFactory.aNullString());

		should.delegateTo(stringParameterConstraints.notANullString())
			.whenCalling(jmockConstraintFactory.notANullString());

		should.delegateTo(stringParameterConstraints.oneOf(severalStrings()))
			.whenCalling(jmockConstraintFactory.oneOf(severalStrings()));

		should.delegateTo(stringParameterConstraints.neitherOf(severalStrings()))
			.whenCalling(jmockConstraintFactory.neitherOf(severalStrings()));

		should.delegateTo(stringParameterConstraints.notEqualTo("notEqualTo"))
			.whenCalling(jmockConstraintFactory.notEqualTo("notEqualTo"));

		should.delegateTo(stringParameterConstraints.equalToIgnoringCase("equalToIgnoringCase"))
			.whenCalling(jmockConstraintFactory.equalToIgnoringCase("equalToIgnoringCase"));

		should.delegateTo(stringParameterConstraints.aStringContaining("aStringContaining"))
			.whenCalling(jmockConstraintFactory.aStringContaining("aStringContaining"));

		should.delegateTo(stringParameterConstraints.aStringNotContaining("aStringNotContaining"))
			.whenCalling(jmockConstraintFactory.aStringNotContaining("aStringNotContaining"));

		should.delegateTo(stringParameterConstraints.aStringMatching("aStringMatching"))
			.whenCalling(jmockConstraintFactory.aStringMatching("aStringMatching"));

		should.delegateTo(stringParameterConstraints.aStringNotMatching("aStringNotMatching"))
			.whenCalling(jmockConstraintFactory.aStringNotMatching("aStringNotMatching"));
	}

	public void testDelegatesToObjectConstaints(DelegateVerify should) {
		should.delegateTo(objectParameterConstraints.anObject())
			.whenCalling(jmockConstraintFactory.anObject());

		should.delegateTo(objectParameterConstraints.aNullObject())
			.whenCalling(jmockConstraintFactory.aNullObject());

		should.delegateTo(objectParameterConstraints.notANullObject())
			.whenCalling(jmockConstraintFactory.notANullObject());

		should.delegateTo(objectParameterConstraints.oneOf(severalObjects()))
			.whenCalling(jmockConstraintFactory.oneOf(severalObjects()));

		should.delegateTo(objectParameterConstraints.neitherOf(severalObjects()))
			.whenCalling(jmockConstraintFactory.neitherOf(severalObjects()));

		Object anObject = new Object();
		should.delegateTo(objectParameterConstraints.notEqual(anObject))
			.whenCalling(jmockConstraintFactory.notEqual(anObject));
	}

	private Object[] severalObjects() {
		return new Object[] {"one", new Integer(2), new Double(3.3)};
	}
	
	private int[] severalIntegers() {
		return new int[] {1, 2, 3, 9, 8, 7};
	}
	
	private long[] severalLongs() {
		return new long[] {100, 200, 300, 900, 800, 700};
	}
	
	private double[] severalDoubles() {
		return new double[] {1.0, 2.0, 3.0, 9.0, 8.0, 7.0};
	}

	private String[] severalStrings() {
		return new String[] {"one", "two", "three"};
	}
}
